﻿using QuanLyGiaoVuService.ReportServices;
using QuanLyGiaoVuUI.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using QuanLyGiaoVuUI.Models.Mappers;
using QuanLyGiaoVuUI.Models.GiangVien;
using QuanLyGiaoVuService.CommandServices;
using QuanLyGiaoVuDAL.DTO;
using QuanLyGiaoVuUI.Models.MonHoc;
using QuanLyGiaoVuUI.Extensions.ExtendedAttributes;
using QuanLyGiaoVuService.CommonServices;

namespace QuanLyGiaoVuUI.Controllers
{
    [GiangVienAuthorize(ChiGiaoVu=true)]
    public class GiangVienController : Controller
    {
        //
        // GET: /GiangVien/
        private IGiangVienReportService _giangVienReportService;
        private IGiangVienCommandService _giangVienCommandService;
        private IMonHocReportService _monHocReportService;
        private IThamSoService _thamSoService;
        private ILopMonHocCommandService _lopMonHocCommandService;
        private ILopMonHocReportService _lopMonHocReportService;
        private IDeTaiCommandService _deTaiCommandService;
        private IDeTaiReportService _deTaiReportService;
        private IHocKyReportService _hocKyReportService;

        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public GiangVienController(
            IGiangVienCommandService giangVienCommandService,
            IGiangVienReportService giangVienReportService, 
            IMonHocReportService monHocReportService,
            IThamSoService thamSoservice,
            ILopMonHocReportService lopMonHocReportService,
            ILopMonHocCommandService lopMonHocCommandService,
            IDeTaiCommandService deTaiCommandService,
            IDeTaiReportService deTaiReportService,
            IHocKyReportService hocKyReportService)
        {
            _giangVienReportService = giangVienReportService;
            _giangVienCommandService = giangVienCommandService;
            _monHocReportService = monHocReportService;
            _thamSoService = thamSoservice;
            _lopMonHocReportService = lopMonHocReportService;
            _lopMonHocCommandService = lopMonHocCommandService;
            _deTaiCommandService = deTaiCommandService;
            _deTaiReportService = deTaiReportService;
            _hocKyReportService = hocKyReportService;
        }

        public ActionResult DanhSachGiangVien()
        {
            IEnumerable<GiangVienViewModel> giangVienViewModelList = GiangVienViewModel.FromGiangVienDTOList(_giangVienReportService.GetAllGiangVien());
            return View("Index",giangVienViewModelList);
        }

        [HttpGet]
        public ActionResult CapNhat(Guid? id)
        {
            CapNhatGiangVienViewModel capnhatGiangVienViewModel = new CapNhatGiangVienViewModel();
            capnhatGiangVienViewModel.DanhSachMonHocGiangDay = new List<MonHocDTO>();
            if (id != null && !id.Equals(Guid.Empty))
            {
                capnhatGiangVienViewModel.ID = (Guid)id;
                capnhatGiangVienViewModel = capnhatGiangVienViewModel.FromGiangVienDTO(_giangVienReportService.GetGiangVienById((Guid)id));
                capnhatGiangVienViewModel.DanhSachMonHocGiangDay = _giangVienReportService.GetAllMonHocByGiangVienId(capnhatGiangVienViewModel.ID);
                capnhatGiangVienViewModel.DanhSachChucVuKiemNhiem = _giangVienReportService.GetAllChucVuGiangVien(capnhatGiangVienViewModel.ID);
                capnhatGiangVienViewModel.DanhSachBoMon = _giangVienReportService.GetAllBoMon();
            }
            capnhatGiangVienViewModel.DanhSachHocVi = _giangVienReportService.GetAllHocVi();
            capnhatGiangVienViewModel.DanhSachHocHam = _giangVienReportService.GetAllHocHam();
            capnhatGiangVienViewModel.DanhSachChucVu = _giangVienReportService.GetAllChucVuChuaKiemNhiemByGiangVienId(capnhatGiangVienViewModel.ID).OrderByDescending( cv => cv.TiLeGiam);
            capnhatGiangVienViewModel.DanhSachChucDanh = _giangVienReportService.GetAllChucDanh();
            return View(capnhatGiangVienViewModel);
        }

        [HttpPost]
        public ActionResult CapNhat(CapNhatGiangVienViewModel capNhatGiangVienViewModel)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var giangvienDTO = capNhatGiangVienViewModel.ToGiangVienDTO();
                    if (giangvienDTO.MaHocHam != null)
                    {
                        var hocVi = _giangVienReportService.GetAllHocVi().Where(hv => hv.MaHocVi == giangvienDTO.MaHocVi).First();
                        if (hocVi != null && hocVi.TenHocVi.ToLower() != "tiến sĩ")
                            ModelState.AddModelError("MaHocHam", "Giảng viên có học hàm Giáo Sư/Phó Giáo Sư phải có học vị Tiến Sĩ.");
                    }
                    _giangVienCommandService.UpdateGiangVien(capNhatGiangVienViewModel.ToGiangVienDTO());
                    return RedirectToAction("DanhSachGiangVien");
                }
            }
            catch (Exception exception)
            {
                log.Error("/GiangVien/CapNhat: " + exception.Message, exception);
            }
            capNhatGiangVienViewModel.DanhSachHocVi = _giangVienReportService.GetAllHocVi();
            capNhatGiangVienViewModel.DanhSachHocHam = _giangVienReportService.GetAllHocHam();
            capNhatGiangVienViewModel.DanhSachChucVuKiemNhiem = _giangVienReportService.GetAllChucVuGiangVien(capNhatGiangVienViewModel.ID);
            capNhatGiangVienViewModel.DanhSachChucVu = _giangVienReportService.GetAllChucVuChuaKiemNhiemByGiangVienId(capNhatGiangVienViewModel.ID).OrderByDescending( cv => cv.TiLeGiam);
            capNhatGiangVienViewModel.DanhSachMonHocGiangDay = _giangVienReportService.GetAllMonHocByGiangVienId(capNhatGiangVienViewModel.ID);
            capNhatGiangVienViewModel.DanhSachChucDanh = _giangVienReportService.GetAllChucDanh();
            capNhatGiangVienViewModel.DanhSachBoMon = _giangVienReportService.GetAllBoMon();
            return View(capNhatGiangVienViewModel);
        }

        [HttpPost]
        [GiangVienAuthorize(ChiGiaoVu=true,ReturnJson=true)]
        public JsonResult ChonBoMon(Guid? maGiangVien, int? maBoMon)
        {
            try
            {
                if (maGiangVien.HasValue && maBoMon.HasValue)
                {
                    _giangVienCommandService.UpdateBoMon(maGiangVien.Value, maBoMon.Value);
                    var dsMonHoc = _monHocReportService.GetAllMonHocByBoMon(maBoMon.Value);
                    var dsMonHocDaDamNhan = _giangVienReportService.GetAllMonHocByGiangVienId(maGiangVien.Value);
                    foreach(var monHoc in dsMonHocDaDamNhan)
                    {
                        _giangVienCommandService.DeleteMonHoc(maGiangVien.Value, monHoc.ID);
                    }
                    foreach (var monHoc in dsMonHoc)
                    {
                        _giangVienCommandService.InsertMonHoc(maGiangVien.Value, monHoc.ID);
                    }
                    return Json(new
                    {
                        success = true,
                        dataList = dsMonHoc.ToArray()
                    });
                }
                return Json(new
                {
                    success = false,
                    message = "Không tìm thấy giảng viên."
                });
            }
            catch (Exception exception)
            {
                log.Error(exception.Message, exception);
                return Json(new { 
                    success = false,
                    message = "Có lỗi xảy ra. Vui lòng thử lại sau."
                });
            }
        }

        [HttpPost]
        public ActionResult Xoa(String[] selectedids)
        {
            string idList = String.Join(",", selectedids);
            _giangVienCommandService.DeleteGiangVienByIds(idList);
            return RedirectToAction("Index");
        }

        [HttpGet]
        public ActionResult ThemMonHoc(Guid? id)
        {
            ViewData["giangVienID"] = id;
            IEnumerable<MonHocViewModel> danhsachMonHoc = MonHocViewModel.FromMonHocDTOList(_giangVienReportService.GetAllMonHocChuaChonByGiangVienId((Guid)id, null));
            return View(danhsachMonHoc);
        }

        [HttpPost]
        public JsonResult ThemMonHoc(Guid giangVienId, String[] selectedIds)
        {
            string result = string.Empty;
            List<MonHocDTO> dsMonHoc = new List<MonHocDTO>();
            bool success;
            try
            {
                foreach (String id in selectedIds)
                {
                    Guid monHocId = new Guid(id);
                    _giangVienCommandService.InsertMonHoc(giangVienId, monHocId);
                    dsMonHoc.Add(_monHocReportService.GetMonHocById(monHocId));
                }
                success = true;
            }
            catch (Exception exception)
            {
                success = false;
                result = "Cập nhật không thành công.";
                log.Error("/GiangVien/ThemMonHoc: " + exception.Message, exception);
            }
            return Json(new { success = success, message = result, dataList = dsMonHoc.ToArray() });
        }

        [HttpPost]
        public JsonResult XoaMon(Guid giangVienId, String selectedIds)
        {
            string result = string.Empty;
            bool success = true;
            string[] ids = selectedIds.Split(',');
            try
            {
                foreach (String idString in ids)
                {
                    Guid id;
                    if (Guid.TryParse(idString, out id))
                        _giangVienCommandService.DeleteMonHoc(giangVienId, id);
                }
                success = true;
            }
            catch (Exception exception)
            {
                log.Error("GiangVien\\XoaMon: " + exception.Message, exception);
                success = false;
                result = "Cập nhật không thành công.";
            }
            return Json(new { 
                success = success,
                message = result
            });
        }

        [HttpPost]
        public JsonResult ThemChucVu(Guid giangVienId, Guid chucVuId)
        {
            try
            {
                _giangVienCommandService.InsertChucVu(giangVienId, chucVuId);
                return Json(new { 
                    success = true,
                    tenChucVu = _giangVienReportService.GetChucVuByChucVuId(chucVuId).TenChucVu
                });
            }
            catch (Exception exception)
            {
                return Json(new { 
                    success = false,
                    message = exception.Message
                });
            }
        }

        [HttpPost]
        public JsonResult XoaChucVu(Guid giangVienId, Guid chucVuId)
        {
            try
            {
                _giangVienCommandService.DeleteChucVu(giangVienId, chucVuId);
                return Json(new
                {
                    success = true,
                    tenChucVu = _giangVienReportService.GetChucVuByChucVuId(chucVuId).TenChucVu
                });
            }
            catch (Exception exception)
            {
                return Json(new
                {
                    success = false,
                    message = exception.Message
                });
            }
        }

        [HttpGet]
        public int SoMonHocChuaDamNhan(Guid? giangVienId)
        {
            if (giangVienId == null)
                return 0;
            else
            {
                IEnumerable<MonHocViewModel> danhsachMonHoc = MonHocViewModel.FromMonHocDTOList(_giangVienReportService.GetAllMonHocChuaChonByGiangVienId((Guid)giangVienId, null));
                return danhsachMonHoc.Count();
            }
        }

        [HttpGet]
        public ActionResult LayDanhSachMonDamNhan(Guid? giangVienId)
        {
            ViewData["giangVienID"] = giangVienId;
            IEnumerable<MonHocViewModel> danhsachMonHoc = MonHocViewModel.FromMonHocDTOList(_giangVienReportService.GetAllMonHocByGiangVienId((Guid)giangVienId));
            return View("ThemMonHoc",danhsachMonHoc);
        }
        public ActionResult ThongKeGioDay()
        {
            IEnumerable<GiangVienViewModel> giangVienViewModelList = GiangVienViewModel.FromGiangVienDTOList(_giangVienReportService.GetAllGiangVien());

            return View(giangVienViewModelList);
        }
        public ActionResult DanhSachHocKy()
        {
            string strMaHK = _thamSoService.GetThamSo("HocKyHienTai");
            Guid hkHienTai = Guid.Parse(strMaHK);

            IEnumerable<HocKyDTO> dsHocKy = _hocKyReportService.GetAllHocKy().OrderBy(hk => hk.TenHocKy).OrderBy(hk => hk.NamHoc.Nam1);
            GiangVienViewModel gv = new GiangVienViewModel();
            gv.DanhSachHocKy = dsHocKy;
            gv.HocKyHienTai = _hocKyReportService.GetHocKyById(hkHienTai);
            return View(gv);
        }
        [HttpGet]
        public ActionResult ThongKeGiangVien(Guid magv,Guid mahk)
        {
           
            GiangVienViewModel giangVienViewModel = new GiangVienViewModel();
            GiangVienDTO giangVienDTO = _giangVienReportService.GetGiangVienById(magv);

            giangVienViewModel = GiangVienViewModel.FromGiangvienDTO(giangVienDTO);

            IEnumerable<ChucVuDTO> gvChucVu = _giangVienReportService.GetAllChucVuGiangVien(magv);
            if (gvChucVu != null)
            {
                giangVienViewModel.DanhSachChucVu = gvChucVu;
            }

            Guid hkHienTai = Guid.Empty;
            if (mahk != null && !mahk.Equals(Guid.Empty))
            {
                hkHienTai = mahk;
            }
            else
            {
                string strMaHK = _thamSoService.GetThamSo("HocKyHienTai");
                hkHienTai = Guid.Parse(strMaHK);
            }

            giangVienViewModel.DanhSachLopMonHoc = _lopMonHocReportService.GetAllLopMonHocTheoGiangVienTrongHocKy(magv,hkHienTai, true, null, true);
            giangVienViewModel.HocKyHienTai = _hocKyReportService.GetHocKyById(hkHienTai);
            giangVienViewModel.DanhSachDeTai = _deTaiReportService.GetAllDeTaiGiangVien(magv, hkHienTai, true);
            giangVienViewModel.DanhSachLopMonHoc = giangVienViewModel.DanhSachLopMonHoc.OrderBy(p => p.LoaiLop);
            
            return View(giangVienViewModel);

        }

        public ActionResult Index()
        {
            return View("Dashboard");
        }
    }
}
